﻿/*****************************************
 * LCD.ILCD
 * Interface for LCD.NET Framework
 * version: 1.3.0
 *  
 * written by: Jason Pruitt
 * contact: lcd-net-framework@gmail.com
 * date: 03/19/2009
 * 
 * description:
 * Provides a .NET Class for interacting with
 * a Hitachi HD44780 or similiar LCD screen thru
 * a rs232 serial interface
 * 
 * requires:
 *      - use of PIC16F690 with LCD.NET.ASM code
 *      - Microsoft .NET Framework 2.0
 *      
 * Copyright ©2009 Jason Pruitt
 * 
 *  This file is part of the LCD.NET Framework.

    LCD.NET Framework is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    LCD.NET Framework is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with LCD.NET Framework.  If not, see <http://www.gnu.org/licenses/>.

 *****************************************/

namespace LCD{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO.Ports;

    /// <summary>
    /// Interface for LCD.NET
    /// </summary>
    /// <remarks>Interface for Display Class, contains all the basic functionality.</remarks>
    /// <example>
    /// <code>
    /// // initialize LCD Display Class
    /// Display LCDdisplay = new Display();
    /// </code>
    /// </example>
    interface ILCD
    {

        #region Connection to LCD

        /// <summary>
        /// Connect to Microcontroller thru Serial Port
        /// </summary>
        /// <param name="com">"COMx" port</param>
        /// <returns>A <see cref='System.Boolean'/> if SerialPort set up or not</returns>
        /// <example>
        /// <code>
        /// 
        /// // initialize LCD Display Class
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// </code>
        /// </example>
        bool connect(string com);
        
        /// <summary>
        /// Connect to Microcontroller thru Serial Port on Default "COM1"
        /// </summary>
        /// <returns>A <see cref='System.Boolean'/> if SerialPort set up or not</returns>
        /// <example>
        /// <code>
        /// 
        /// // initialize LCD Display Class
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect();
        /// 
        /// </code>
        /// </example>
        bool connect();
        
        /// <summary>
        /// Close Serial Port
        /// </summary>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // write text to screen on line 1
        /// LCDdisplay.write("Hello World", 1);
        /// 
        /// // close connection
        /// LCDdisplay.close();
        /// </code>
        /// </example>
        void close();
        
        #endregion

        #region Set Up Display
        /// <summary>
        /// Set up LCD functions
        /// </summary>
        /// <param name="s8bit">True for 8 bit mode False for 4 bit mode (hardware specific)</param>
        /// <param name="s2line">True for 2 line mode False for 1 line mode</param>
        /// <param name="s5x11">True for 5x11 mode False for 5x8 font size</param>
        /// <param name="s2seg">True for 2 segment LCD screens (hardware specific)</param>
        /// <param name="sLCDHeight">Number of Lines on Display</param>
        /// <param name="sLCDWidth">Length of Display lines</param>/// <remarks>
        /// <para>Used for changing initial start up options</para>
        /// <para>Default 8 bit, 2 line mode, 5x8 font size, 2 segments, 4 lines, 40 characters</para>
        /// <para>Uses <see cref="segment"/> value</para>
        /// <para>s8bit, s2line, s5x11 are for the actual LCD screen. s2seg, sLCDHeight, sLCDWidth are for Display Class</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // for two segment displays
        /// // set to segment desired
        /// LCDdisplay.segment = "both"; 
        /// 
        /// // set up LCD display for 8 bit mode, 2 line, 5x8 fontsize
        /// // 2 segments, and a display size of 4 lines by 40 characters
        /// LCDdisplay.display_setup(true,true,false,true,4,40);
        /// </code>
        /// </example>
        void display_setup(bool s8bit, bool s2line, bool s5x11, bool s2seg, int sLCDHeight, int sLCDWidth);

        /// <summary>
        /// Set or Get if LCD Display is On or Off
        /// </summary>
        /// <returns>A <see cref='System.Boolean'/> True if On, False if Off</returns>
        /// <remarks>
        /// <para>Accepts and Returns <see cref='System.Boolean' /> value </para>
        /// <para>Default On</para>
        /// <para>Uses <see cref="segment"/> value</para>
        /// <para>On two segment displays, the value is going to be the last used, not necessarily the value of that segment</para>
        /// </remarks> 
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // find out if display is on
        /// // if not, turn on
        /// if(!display_on)
        /// {
        ///     LCDdisplay.display_on = true;
        /// }
        /// </code>
        /// </example>
        bool display_on { get; set; }

        /// <summary>
        /// Set or Get Cursor Underline On or Off
        /// </summary>
        /// <returns>A <see cref='System.Boolean'/> True if On, False if Off</returns>
        /// <remarks>
        /// <para>Accepts a <see cref='System.Boolean' /> value </para>
        /// <para>Default Off</para>
        /// <para>Uses <see cref="segment"/> value</para>
        /// <para>On two segment displays, the value is going to be the last used, not necessarily the value of that segment</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // for two segment displays
        /// // set to segment desired
        /// LCDdisplay.segment = "both";
        /// 
        /// // Set underline on for both segments
        /// LCDdisplay.display_underline = true;
        /// 
        /// // Both segments of display now have underline cursor
        /// </code>
        /// </example>
        bool display_underline { get; set; }

        /// <summary>
        /// Set or Get Cursor Blink On or Off
        /// </summary>
        /// <returns>A <see cref='System.Boolean'/> True if On, False if Off</returns>
        /// <remarks>
        /// <para>Accepts a <see cref='System.Boolean' /> value</para>
        /// <para>Default Off</para>
        /// <para>Uses <see cref="segment"/> value</para>
        /// <para>On two segment displays, the value is going to be the last set, not necessarily the value of that segment</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // for two segment displays
        /// // set to segment desired
        /// LCDdisplay.segment = "bottom";
        /// 
        /// // find out if blink is on
        /// // if not, turn on
        /// if(!display_blink)
        /// {
        ///     LCDdisplay.display_blink = true;
        /// }
        /// 
        /// // Bottom segment of display now has a blinking cursor
        /// </code>
        /// </example>
        bool display_blink { get; set; }

        /// <summary>
        /// Set or Get Display Direction, Right or Left
        /// </summary>
        /// <returns>A <see cref='System.String'/> "right" or "left"</returns>
        /// <remarks>
        /// <para>Accepts a <see cref='System.String' /> "right" or "left"</para>
        /// <para>Default Right</para>
        /// <para>Uses <see cref="segment"/> value</para>
        /// <para>On two segment displays, the value is going to be the last used, not necessarily the value of that segment</para>
        /// <para>
        /// Warning!: When set to Left could cause some issues since DDRAM/CGRAM in the LCD Display goes in reverse.
        ///  Because of this, when set to Left <see cref='set_user_defined_character' /> and <see cref='get_user_defined_character' />
        ///  do not work at all.
        ///  </para>
        ///  <para>Works in conjunction with <see cref='display_shift' /></para>
        /// <para>display_shift = true entire display moves in this direction on text write</para>
        /// <para>display_shift = false text is printed in this direction on text write</para>
        /// </remarks> 
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // for two segment displays
        /// // set to segment desired
        /// LCDdisplay.segment = "both";
        /// 
        /// // Set direction to left
        /// LCDdisplay.display_direction = "left";
        /// 
        /// // Both segments of display now print
        /// // text from right to left
        /// </code>
        /// </example>
        string display_direction{ get; set; }

        /// <summary>
        /// Set or Get Display Shift, On or Off
        /// </summary>
        /// <returns>A <see cref='System.Boolean'/> True if On False if Off</returns>
        /// <remarks>
        /// <para>Use <see cref='display_direction' /> to control which direction</para>
        /// <para>Default Off</para>
        /// <para>Uses <see cref="segment"/> value</para>
        /// <para>On two segment displays, the value is going to be the last used, not necessarily the value of that segment</para>
        /// <para>
        /// Warning!: When <see cref='display_direction' /> set to Left could cause some issues since DDRAM/CGRAM in the LCD Display goes in reverse.
        ///  Because of this, when set to Left <see cref='set_user_defined_character' /> and <see cref='get_user_defined_character' />
        ///  do not work at all.
        ///  </para>
        /// <para>display_shift = true entire display moves in direction of <see cref='display_direction' /> on text write</para>
        /// <para>display_shift = false text is printed in direction of <see cref='display_direction' /> on text write</para>
        /// </remarks> 
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // for two segment displays
        /// // set to segment desired
        /// LCDdisplay.segment = "top";
        /// 
        /// // set shift on
        /// LCDdisplay.display_shift = true;
        /// 
        /// // Set direction to left
        /// LCDdisplay.display_direction = "left";
        /// 
        /// // Bottom segment Display now shifts left
        /// // on text write, with cursor staying in 
        /// // same position on screen
        /// </code>
        /// </example>
        bool display_shift { get; set; }

        /// <summary>
        /// Gets Length of the Display Line
        /// </summary>
        /// <remarks>
        /// <para>Returns an <see cref='System.Int32' /> of the length of the display</para>
        /// <para>Indexed at 1, so a 4x20 display would return 20 not 19, which 19 would
        /// be the cursor position of the last character on the line.</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // set to line 2
        /// // must use line here, as write("text",2)
        /// // would reset position to 0
        /// LCDdisplay.line = 2;
        /// 
        /// // get difference between line length and text length
        /// decimal cOffset1 = LCDdisplay.line_length - text.Length;
        /// 
        /// // divide that number by 2 and round down
        /// // to nearest whole number
        /// decimal cOffset2 = Math.Floor(cOffset1 / 2);
        /// 
        /// // convert to Int
        /// int centerOffset = Convert.ToInt32(cOffset2);
        /// 
        /// // and then move cursor to that position
        /// // to center text on display
        /// LCDdisplay.move_cursor_to(centerOffset);
        /// 
        /// 
        /// // then write characters
        /// LCDdisplay.write("Hello World");
        /// 
        /// // Display now shows Hello World centered on line 2
        /// </code>
        /// </example>
        int line_length { get; }
        #endregion

        #region User Defined Characters
        /// <summary>
        /// Create User Defined Characters
        /// </summary>
        /// <param name="addr">Address in CGRAM to use 0-14 depending on LCD hardware</param>
        /// <param name="char_design">8x5 array containing character design</param>
        /// <remarks>
        /// <para>Warning!: Does not work when <see cref='display_direction' /> is set to Left. Since DDRAM/CGRAM goes in reverse</para> 
        /// <para>Uses <see cref='line' /> value and writes to the segment's CGRAM that line is on</para>
        /// </remarks>        
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // create user defined character byte array
        /// // true lights up on display, false is empty
        /// bool[,] char_design = {
        ///                      {true ,false,false,false,true }, // line 1
        ///                      {false,true ,false,true ,false}, // line 2
        ///                      {false,false,true ,false,false}, // line 3
        ///                      {false,true ,false,true ,false}, // line 4
        ///                      {true ,false,false,false,true }, // line 5
        ///                      {false,false,false,false,false}, // line 6
        ///                      {false,false,false,false,false}, // line 7
        ///                      {false,false,false,false,false}  // line 8 usually left clear for cursor
        ///                      };//1    2     3     4     5 
        /// // create character
        /// // in address 0
        /// LCDdisplay.set_user_defined_character(0,char_design);
        /// 
        /// // print character to current cursor position
        /// LCDdsiplay.get_user_defined_character(0);
        /// </code>
        /// </example>        
        void set_user_defined_character(int addr, bool[,] char_design);

        /// <summary>
        /// Write User Defined Character To LCD Display
        /// </summary>
        /// <param name="addr">Address in CGRAM to use 0-14 depending on LCD hardware</param>
        /// <returns>A <see cref='System.Boolean' /> True if <paramref name="addr" /> was with in limits 0-14</returns>
        /// <remarks>
        /// <para>Warning!: Does not work when <see cref='display_direction' /> is set to Left. Since DDRAM/CGRAM goes in reverse</para> 
        /// <para>Uses <see cref='line' /> value and writes to the segment's CGRAM that line is on</para>
        /// </remarks>        
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // create user defined character byte array
        /// // true lights up on display, false is empty
        /// bool[,] char_design = {
        ///                      {true ,false,false,false,true }, // line 1
        ///                      {false,true ,false,true ,false}, // line 2
        ///                      {false,false,true ,false,false}, // line 3
        ///                      {false,true ,false,true ,false}, // line 4
        ///                      {true ,false,false,false,true }, // line 5
        ///                      {false,false,false,false,false}, // line 6
        ///                      {false,false,false,false,false}, // line 7
        ///                      {false,false,false,false,false}  // line 8 usually left clear for cursor
        ///                      };//1    2     3     4     5 
        /// // create character
        /// // in address 1
        /// LCDdisplay.set_user_defined_character(1,char_design);
        /// 
        /// // print character to current cursor position
        /// LCDdsiplay.get_user_defined_character(1);
        /// </code>
        /// </example>
        bool get_user_defined_character(int addr);
        #endregion

        #region Segment and Line selection
        /// <summary>
        /// Set or Get Which Segment LCD should use
        /// </summary>
        /// <returns>A <see cref='System.String'/> of "Top", "Bottom", or "Both"</returns>
        /// <remarks>
        /// <para>Accepts <see cref='System.String' /> of "Top", "Bottom", or "Both"</para>
        /// <para>Default Both</para>
        /// <para>
        /// If your LCD only has only one segment. Its not necessary to worry about this setting at all.
        /// Does not set value in microcontroller directly, but is used during instruction writes.
        /// Important to understand which method or property is going to use this, vs <see cref='line' />. To
        /// make sure the method or property is going to the segment you want it too.
        /// Internally any method that uses this, will set microcontroller back to the previous line value after execution
        /// </para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // set segment to bottom
        /// LCDdisplay.segment = "bottom";
        /// 
        /// // set blink on bottom segment
        /// LCDdisplay.display_blink = true;
        /// 
        /// // set segment to top
        /// LCDdisplay.segment = "top";
        /// 
        /// // turn off blink on top segment
        /// LCDdisplay.display_blink = false;
        /// 
        /// // Now top segment's cursor doesn't
        /// // blink and bottom segment's does
        /// </code>
        /// </example>
        string segment {get; set;}

        /// <summary>
        /// Set or Get Which line LCD should use
        /// </summary>
        /// <returns>A <see cref='System.Int32' /> 1-4 depending on which line currently selected</returns>
        /// <remarks>
        /// <para>Accepts a <see cref='System.Int32' /> 1-4</para>
        /// <para>Default 1</para>
        /// <para>
        /// Sets value DDRAM in microcontroller directly. But read and write character methods that are based off this,
        /// like during a <see cref='get_cursor_position()' /> call will return an <see cref='System.Int32' /> in relation to the the
        /// line that is currently selected, instead of the DDRAM address.
        /// </para> 
        /// <para>
        /// Important to understand which method or property is going to use this, vs <see cref='segment' />.
        /// </para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // set to line 2
        /// LCDdisplay.line = 2;
        /// 
        /// // get cursor position
        /// int curPos = LCDdisplay.get_cursor_position();
        /// 
        /// // move cursor ahead 5 spots
        /// LCDdisplay.move_cursor_to(curPos + 5)
        /// 
        /// // write characters to that position 
        /// LCDdisplay.write("5 ahead on line 2");
        /// 
        /// // LCDdisplay.line still equals 2
        /// 
        /// // write characters line 3
        /// LCDdisplay.write("at beginning of line 3",3);
        /// 
        /// // LCDdisplay.line now equals 3
        /// 
        /// </code>
        /// </example>
        int line { get; set; }
        #endregion

        #region Clear Display

        /// <summary>
        /// Clear Display of Characters 
        /// </summary>
        /// <remarks>
        /// <para>Clears contents of currently selected <see cref='segment' /> value, But leaves cursor in current position.
        /// If <see cref='display_blink'/> or <see cref='display_underline'/> is on, cursor will remain visible</para>
        /// <para>Uses <see cref='segment'/> value</para>
        /// <para>On two segment displays, the value is going to be the last used, not necessarily the value of that segment.</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // turn on underline
        /// LCDdisplay.display_underline() = true;
        /// 
        /// // write characters to line 3
        /// LCDdisplay.write("write to line 3",3);
        /// 
        /// // clear display
        /// LCDdisplay.clear_display();
        /// 
        /// // Display is clear of all text and 
        /// // cursor with underline is at position 15
        /// </code>
        /// </example>
        void clear_display();

        #endregion        

        #region Clear Lines
        /// <summary>
        /// Clear Line of Characters from current cursor position
        /// </summary>
        /// <remarks>
        /// <para>Clears contents of currently selected <see cref='line' />, from where ever
        /// the cursor is, to the end of the line and leaves cursor at end of the line.
        /// If <see cref='display_blink'/> or <see cref='display_underline'/> is on, cursor will remain visible.</para>
        /// <para>Uses <see cref='line'/> value</para>
        /// <para>Basically it writes space characters the entire length of the display.</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // set to line 2
        /// LCDdisplay.line = 2;
        /// 
        /// // write characters to line 2
        /// LCDdisplay.write("Hello World");
        /// 
        /// // move cursor
        /// LCDdisplay.move_cursor_to(5);
        /// 
        /// // clear display
        /// LCDdisplay.clear_line();
        /// 
        /// // Line 2 now just says "Hello"
        /// </code>
        /// </example>
        void clear_line();

        /// <summary>
        /// Clear Line of Characters
        /// </summary>
        /// <param name="line">Line Number</param>
        /// <remarks>
        /// <para>Clears contents of currently selected <see cref='line' />, and leaves cursor at end of the line.
        /// If <see cref='display_blink'/> or <see cref='display_underline'/> is on, cursor will remain visible.</para>
        /// <para>Uses and sets <see cref='line'/> value</para>
        /// <para>Basically it writes space characters the entire length of the display.</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // set to line 2
        /// LCDdisplay.line = 2;
        /// 
        /// // write characters to line 2
        /// LCDdisplay.write("Hello World");
        ///
        /// // clear display
        /// LCDdisplay.clear_line(2);
        /// 
        /// // Line 2 is now blank
        /// </code>
        /// </example>
        void clear_line(int line);
        #endregion

        #region Move Cursor and Display
        /// <summary>
        /// Move Cursor From Current Cursor Position "Right" "Left" or "Home"
        /// </summary>
        /// <param name="move">"Right" "Left" or "Home"</param>
        /// <remarks>
        /// <para>"Right" and "Left" move cursor one position in that direction. "Home" moves to cursor position 0 of line 1.</para>
        /// <para>Default Right</para>
        /// <para>Home uses <see cref="segment"/> value. Right Left uses <see cref="line"/></para>
        /// <para>On two segment displays, the value is going to be the last used, not necessarily the value of that segment</para>
        /// <para>Limited by line_length and Start of line to prevent DDRAM issues. Will wrap from
        /// 0 to end of line going left, or end of line to 0 if going right. If Home used on
        /// two segment display moves cursor to current segments line 1 (or line 3 on Display)</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // set to line 2
        /// LCDdisplay.line = 2;
        /// 
        /// // write characters to line 2
        /// LCDdisplay.write("Value equals 2");
        /// 
        /// // Line 2 now says "Value equals 2"
        /// 
        /// // move cursor
        /// LCDdisplay.move_cursor("left");
        /// 
        /// // write character
        /// LCDdisplay.write("3");
        /// 
        /// // Line 2 now says "Value equals 3"
        /// 
        /// </code>
        /// </example> 
        void move_cursor(string move);

        /// <summary>
        /// Shift Display "Left" or "Right"
        /// </summary>
        /// <param name="move">"Right" "Left"</param>
        /// <remarks>
        /// <para>"Right" and "Left" move Display one position in that direction.</para>
        /// <para>Default Right</para>
        /// <para>Text remains in same DDRAM position, but DDRAM changes in relation to its position on the LCD display.
        /// So position 0 after a right shift, is displayed in position 1 on the display.</para>
        /// <para>Uses <see cref="segment"/> value</para>
        /// <para>On two segment displays, the value is going to be the last used, not necessarily the value of that segment</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // write characters to line 2
        /// LCDdisplay.write("Hello World",2);
        /// 
        /// // move display left
        /// LCDdisplay.move_display("left");
        /// 
        /// // screen now displays "ello World"
        /// // depending on DDRAM addressing H 
        /// // could be display elsewhere on screen
        /// 
        /// // move display right
        /// LCDdisplay.move_display("right");
        /// 
        /// // screen now displays "Hello World"
        /// 
        /// </code>
        /// </example> 
        void move_display(string move);

        /// <summary>
        /// Move Cursor to Specified Position
        /// </summary>
        /// <param name="position">Cursor position</param> 
        /// <remarks>
        /// <para>0 indexed.</para>
        /// <para>Limited by length of display, if longer than length it defaults to end position. If less than 0 set to 0.</para>
        /// <para>Uses <see cref="line"/> value</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // set to line 2
        /// LCDdisplay.line = 2;
        /// 
        /// // write characters to line 2
        /// LCDdisplay.write("Hello World");
        /// 
        /// // move cursor
        /// LCDdisplay.move_cursor_to(5);
        /// 
        /// // clear display
        /// LCDdisplay.clear_line();
        /// 
        /// // Line 2 now just says Hello
        /// </code>
        /// </example>     
        void move_cursor_to(int position);
        #endregion

        #region Write Text
        /// <summary>
        /// Write Text to LCD
        /// </summary>
        /// <param name="text">Text</param>
        /// <remarks>
        /// <para>Writes text starting at current cursor position.</para>
        /// <para>Limited by length of display, if longer than length it defaults to end position. If less than 0 set to 0.</para>
        /// <para>Uses <see cref='line'/> value</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // set to line 2
        /// LCDdisplay.line = 2;
        /// 
        /// // write characters to line 2
        /// LCDdisplay.write("Hello World");
        /// 
        /// // Display now shows Hello World on line 2
        /// </code>
        /// </example> 
        void write(string text);

        /// <summary>
        /// Write Text to LCD on specified line
        /// </summary>
        /// <param name="text">Text</param>
        /// <param name="line">Line number</param>
        /// <remarks>
        /// <para>Writes text from beginning of the selected line.</para>
        /// <para>Limited by length of display, if <paramref name="text" /> is longer than length it defaults to end position.</para>
        /// <para>Uses and sets <see cref='line'/> value</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // write characters to line 2
        /// LCDdisplay.write("Hello World",2);
        /// 
        /// // Display now shows Hello World at beginning of line 2
        /// </code>
        /// </example> 
        void write(string text, int line);
        #endregion

        #region Read Data
        /// <summary>
        /// Read Character Rrom Current Cursor Position.
        /// </summary>
        /// <returns>A <see cref='System.String'/> Character</returns>
        /// <remarks>
        /// <para>Returns character at cursor position then advances cursor one position</para>
        /// <para>Uses <see cref='line'/> value</para>
        /// <para>Limited by line_length and Start of line to prevent DDRAM issues. Will wrap from
        /// 0 to end of line going left, or end of line to 0 if going right.</para>
        /// <para>If reading a character created with <see cref='set_user_defined_character' /> will not be printable character,
        /// custom characters are byte value 00000000 thru 00001110, which are ascii control characters.</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // write characters to line 2
        /// LCDdisplay.write("Hello World",2);
        /// 
        /// // move cursor
        /// LCDdisplay.move_cursor("left");
        /// 
        /// // read character
        /// string readChar = LCDdisplay.read_character();
        /// 
        /// // readChar now contains the value "d"
        /// </code>
        /// </example> 
        string read_character();

        /// <summary>
        /// Get Current Cursor Position
        /// </summary>
        /// <returns>A <see cref='System.Int32'/> Current cursor position</returns>
        /// <remarks>
        /// <para>Gets cursor position relative to the line the cursor is on, 0 indexed. Not the DDRAM address.</para> 
        /// <para>Uses <see cref='line'/> value</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // write characters to line 2
        /// LCDdisplay.write("Hello World",2);
        /// 
        /// // move cursor
        /// LCDdisplay.move_cursor("left");
        /// 
        /// // read character
        /// int curPos = LCDdisplay.get_cursor_position();
        /// 
        /// // curPos now contains value 10
        /// </code>
        /// </example> 
        int get_cursor_position();
        #endregion

        #region Experimental Hardware Code
        /// <summary>
        /// Set or Get Backlight On or Off
        /// </summary>
        /// <returns>A <see cref='System.Boolean'/> True if On, False if Off</returns>
        /// <remarks>
        /// <para>::!Experimental Code!:: Requires extra hardware</para>
        /// <para>Accepts a <see cref='System.Boolean' /> value</para>
        /// <para>Default On</para>
        /// </remarks>
        /// <example>
        /// <code>
        /// // initialize LCD Display
        /// Display LCDdisplay = new Display();
        /// 
        /// // open connection to serial port
        /// LCDdisplay.connect("COM1");
        /// 
        /// // find out if backlight is on
        /// // if not, turn on
        /// if(!backlight_on)
        /// {
        ///     LCDdisplay.backlight_on = true;
        /// }
        /// 
        /// // Backlight should now be on
        /// </code>
        /// </example>
        bool backlight_on { get; set; }
        #endregion
    }
}
